package jee.boot.module.log.aspect;

import jee.boot.common.properties.ProjectConfig;
import jee.boot.common.utils.StringUtils;
import jee.boot.entity.log.LeaveTraces;
import jee.boot.entity.log.LogEntity;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

/**
 * 留痕的AOP
 */
@Aspect
@Component
public class LeaveTracesAspect {
    private Log logger = LogFactory.getLog(LeaveTracesAspect.class);
    @Autowired
    private ProjectConfig projectConfig;
    @Autowired
    private HttpServletRequest request; //自动注入request
    /**
     * 默认匹配LeaveTraces注解的所有方法
     */
    @Pointcut("@annotation(jee.boot.entity.log.LeaveTraces)")
    public void log(){
    }

    /**
     * 被拦截的方法执行后,进行日志记录,默认只对当前方法的第一个参数进行存储,比如 save(User user,Company company),只对user进行日志记录
     * @param joinPoint
     * @param leaveTraces
     */
    @After("log()&&@annotation(leaveTraces)")
    public void doAfter(JoinPoint joinPoint, LeaveTraces leaveTraces){
        //获取传入目标方法的参数
        Object[] args = joinPoint.getArgs();
        if(args!=null && args.length>0){
            LogEntity log=new LogEntity();
            Object entity= args[0];
            log.setProjectName(projectConfig.getName());
            log.setServiceName(joinPoint.getSignature().getDeclaringTypeName()+"."+joinPoint.getSignature().getName());
            log.setOperator(leaveTraces.operator().toString());
            log.setEntityName(entity.getClass().getName());
            String remoteAddr=request.getRemoteAddr();
            String realIp = request.getHeader("x-real-ip");
            // 添加客户主机的真是ip
            if(StringUtils.isNotBlank(realIp)){
                remoteAddr=realIp;
            }
            log.setRemoteAddr(remoteAddr);
            try {
               String id=(String) PropertyUtils.getProperty(entity, "id");
               log.setEntityId(id);
            } catch (Exception e) {
                //获取数据主键出错的时候,设置为null主键
                log.setEntityId("null");
            }
            log.setEntity(entity);
            logger.info(log.toString());
        }

    }
}
